﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Gear.ToolKits.Helper
{
    /// <summary>
    /// 内存缓存帮助类
    /// </summary>
    public static class MemoryCacheHelper
    {
        public static readonly IMemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions
        {
        });
        /// <summary>
        /// 默认缓存
        /// </summary>
        public static IMemoryCache Cache
        {
            get
            {
                return memoryCache;
            }
        }

        /// <summary>
        /// 删除所有缓存
        /// </summary>
        public static void RemoveCacheAll()
        {
            var keys = GetCacheKeys();
            foreach (var key in keys)
            {
                Cache.Remove(key);
            }
        }


        /// <summary>
        /// 获取所有缓存键
        /// </summary>
        /// <returns></returns>
        public static List<string> GetCacheKeys()
        {
            const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
            var entries = Cache.GetType().GetField("_entries", flags).GetValue(Cache);
            var cacheItems = entries as IDictionary;
            var keys = new List<string>();
            if (cacheItems == null) return keys;
            foreach (DictionaryEntry cacheItem in cacheItems)
            {
                keys.Add(cacheItem.Key.ToString());
            }
            return keys;
        }

        /// <summary>
        /// 获取Key对应的缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(object key)=>Cache.Get<T>(key);

       /// <summary>
       /// 自定义缓存
       /// </summary>
       /// <param name="key"></param>
       /// <returns>活性缓存失活后重置缓存</returns>
        public static object GetOrCreate(object key,int sliding=0,int absolute=0)
        {
            sliding = sliding > absolute ? absolute : sliding;
            var res=Cache.GetOrCreate(key, entry =>
            {

                if (sliding > 0)entry.SlidingExpiration = TimeSpan.FromSeconds(sliding);  // 滑动缓存时间（一定时间没有使用则删除）
                if (absolute > 0) entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(absolute);  // 绝对缓存时间（一定时间后立即删除），切需要大于滑动时间
                return entry.Value;

            });
            return res;
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Set<T>(object key, T value) => Cache.Set(key, value);
    }
}
